﻿using System;
using System.Collections.Generic;
using System.Data.Services.Common;
using System.Text;
using System.Linq;

namespace WASM.WebSite.Logic
{
	public class TableGenericProperty
	{
		public string Key
		{
			get;
			set;
		}

		public object Value
		{
			get;
			set;
		}
	}

	[DataServiceKey("PartitionKey", "RowKey")]
	public class TableGenericEntity
	{
		public string PartitionKey { get; set; }
		public string RowKey { get; set; }

		List<TableGenericProperty> _properties = new List<TableGenericProperty>();

		public List<TableGenericProperty> Properties
		{
			get
			{
				return _properties;
			}
			set
			{
				_properties = value;
			}
		}

		internal object this[string key]
		{
			get
			{
				return this._properties.Single(e => e.Key == key);
			}

			set
			{
				if (!_properties.Exists(e=>e.Key == key))
					_properties.Add(new TableGenericProperty() {Key = key, Value = value});
				else 
					_properties.SingleOrDefault(e => e.Key == key).Value = value;
			}
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			string value;
			int count = 0;
			if (_properties != null)
			{
				foreach (TableGenericProperty kvp in _properties)
				{
					if (count > 0)
						sb.Append("|");
					if (kvp.Value == null)
						value = string.Empty;
					else
						value = kvp.Value.ToString();
					sb.Append(kvp.Key + "=" + value);
					count++;
				}
			}
			return sb.ToString();
		}

		public string ToXml()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("<entity>");       // RowKey=\"" + this.RowKey + "\">");
			sb.AppendLine("  <PartitionKey>" + this.PartitionKey + "</PartitionKey>");
			sb.AppendLine("  <RowKey>" + this.RowKey + "</RowKey>");

			string value;
			if (_properties != null)
			{
				foreach (TableGenericProperty kvp in _properties)
				{
					if (kvp.Value == null)
						value = string.Empty;
					else
						value = kvp.Value.ToString();
					sb.AppendLine("  <" + kvp.Key + ">" + value + "</" + kvp.Key + ">");
				}
			}

			sb.AppendLine("</entity>");
			return sb.ToString();
		}

		public string ToXmlBinaryValues()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("<entity>");       // RowKey=\"" + this.RowKey + "\">");
			sb.AppendLine("  <PartitionKey>" + this.PartitionKey + "</PartitionKey>");
			sb.AppendLine("  <RowKey>" + this.RowKey + "</RowKey>");

			string value;
			if (_properties != null)
			{
				foreach (TableGenericProperty kvp in _properties)
				{
					if (kvp.Value == null)
						value = string.Empty;
					else
						value = kvp.Value.ToString();

					value = DisplayCharsAsBytes(value.ToCharArray());

					sb.AppendLine("  <" + kvp.Key + ">" + value + "</" + kvp.Key + ">");
				}
			}

			sb.AppendLine("</entity>");
			return sb.ToString();
		}

		/// Convert a byte sequence into a displayable multi-line string showing the values.
		/// </summary>
		/// <param name="bytes"></param>
		/// <returns></returns>

		private string DisplayBytes(byte[] bytes)
		{
			StringBuilder sb = new StringBuilder();

			for (int b = 0; b < bytes.Length; b++)
				sb.Append(String.Format("{0:X2}", bytes[b]) + " ");
			return sb.ToString();
		}

		private string DisplayCharsAsBytes(char[] chars)
		{
			StringBuilder sb = new StringBuilder();

			for (int b = 0; b < chars.Length; b++)
				sb.Append(String.Format("{0:X4}", Convert.ToInt64(char.GetNumericValue(chars[b]))) + " ");
			return sb.ToString();
		}
	}
}
